package sistemaClassificador.algoritmoGenetico;

import util.Logger;
import weka.core.Instance;
import weka.core.Instances;

public class Classificador {

	public String getResultado() {
		return resultado;
	}
	private Logger log = new Logger(this);
	private Populacao listaRegra;
	private double TP = 0;
	private double FP = 0;
	private double TN = 0;
	private double FN = 0;
	private int regra_nao_identificada;
	private int regra_identificada;
	private String resultado;

	public Classificador(Populacao listaRegra) {
		this.listaRegra = listaRegra;
	}

	public void executar(Instances input) {
		log.info("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
		log.info("--  Classificador");
		log.info("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
		log.info("Missao : Classificar " + input.numInstances()
				+ " instancias.");
		log.info("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
		for (int a = 0; a < input.numInstances(); a++) {
			verificarElemento(input.instance(a));
		}
		log.info("Acertou               = " + TP + " per: "
				+ (percentual(TP + FP, TP)) + "%");
		log.info("Errou                 = " + FP + " per: "
				+ percentual(TP + FP, FP) + "%");
		log.info("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
		log.info("Nao identificou regra = "
				+ regra_nao_identificada
				+ " per: "
				+ percentual(
						(TP + FP + regra_nao_identificada),
						regra_nao_identificada) + "%");
		log.info("Identificou regra     = "
				+ regra_identificada
				+ " per: "
				+ percentual(
						(TP + FP + regra_nao_identificada),
						regra_identificada) + "%");
		log.info("Total                 = "
				+ (TP + FP + regra_nao_identificada));
		log.info("TP                 = "
				+ (TP));
		log.info("FP                 = "
				+ (FP));
		log.info("TN                 = "
				+ (TN));
		log.info("FN                 = "
				+ (FN));
	
	}

	private void verificarElemento(Instance i) {
		int a = 0;
		double maior_fitness=0;
		int ind_regra=0;
		double maior_fitness2=0;
		int ind_regra2=0;
		for (a = 0; a < listaRegra.size(); a++) {
			/*
			 * Verifica se a regra se aplica ao elemento
			 */
			if (compararRegra(i, listaRegra.getRegra(a))) {
				if(listaRegra.getRegra(a).getFitness()>maior_fitness){
					maior_fitness = listaRegra.getRegra(a).getFitness();
					ind_regra = a;
				}
			}
			else{
				if(listaRegra.getRegra(a).getFitness()>maior_fitness2){
					maior_fitness2 = listaRegra.getRegra(a).getFitness();
					ind_regra2 = a;
				}
		    }
		}	
			if(maior_fitness > 0){
				regra_identificada++;
				if (verificarClasse(i, listaRegra.getRegra(ind_regra))) {
					/*
					 * Acertou a regra e classe
					 */
					TP++;
				} else {
					/*
					 * Acertou a regra mas errou a classe
					 */
					FP++;
				}
			}
			else{
				regra_nao_identificada++;
				if (verificarClasse(i, listaRegra.getRegra(ind_regra2))) {
					/*
					 * Errou a regra e acertou classe
					 */
					FN++;
				} else {
					/*
					 * Errou a regra e a classe
					 */
					TN++;
				}
			}	
	
	}
	private boolean verificarClasse(Instance i, Regra regra) {
		String c = i.stringValue(i.numAttributes() - 1).toString();
		String c1 = regra.getClasse();
		/*
		 * Verifica se a regra da classe e a mesma do elemento
		 */
		return c.equals(c1);
	}

	private boolean compararRegra(Instance i, Regra regra) {
		for (int a = 0; a < regra.size(); a++) {
			try {
				if (regra.getCondicao(a).isAtivo()) {
					String str = regra.getCondicao(a).getElemento();
					String str2 = i.stringValue(a).toString();
					if (!regra.getCondicao(a).getComparacao()
							.comparar(str, str2)) {
						return false;
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return true;
	}

	private double percentual(double total, double parcial) {
		return ((parcial * 100) / total);
	}

}
